package com.szw.learn.websocket;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import com.szw.learn.bean.SendMessageBean;
import com.szw.learn.util.JsonUtil;
import com.szw.learn.util.UuidUils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

import com.szw.learn.redismq.PublishService;
import com.szw.learn.redismq.SubscribeListener;
import com.szw.learn.util.SpringUtils;
/**
 *@ServerEndpoint(value="/websocket")value值必须以/开路
 *备注:@ServerEndpoint注解类不支持使用@Autowire
 *{topic}指：向哪个频道主题里发消息
 *{myname}指：这个消息是谁的。真实环境里可以使用当前登录用户信息
 */
@Component
//@ServerEndpoint(value="/websocket/{topic}/{myname}")
@ServerEndpoint(value="/websocket/{myname}")
public class WebsocketEndpoint {
	
	/**
	 * 因为@ServerEndpoint不支持注入，所以使用SpringUtils获取IOC实例
	 */
	private StringRedisTemplate redisTampate = SpringUtils.getBean(StringRedisTemplate.class);
	
	private RedisMessageListenerContainer redisMessageListenerContainer = SpringUtils.getBean(RedisMessageListenerContainer.class);
	
	//存放该服务器该ws的所有连接。用处：比如向所有连接该ws的用户发送通知消息。
	//private static CopyOnWriteArraySet<WebsocketEndpoint> sessions = new CopyOnWriteArraySet<>();
	private static Map<String, WebsocketEndpoint> clients = new ConcurrentHashMap<String, WebsocketEndpoint>();
	
	private Session session;
	private String myname;
	private String key;
	
	@OnOpen
	public void onOpen(Session session,@PathParam("myname")String myname){
		System.out.println("java websocket:打开连接");
		this.session = session;
		this.myname = myname;
		this.key = UuidUils.getUuid();
		//sessions.add(this);
		clients.put(key,this);
		SubscribeListener subscribeListener = new SubscribeListener();
		subscribeListener.setSession(session);
		subscribeListener.setStringRedisTemplate(redisTampate);
		//设置订阅topic
		//redisMessageListenerContainer.addMessageListener(subscribeListener, new ChannelTopic(topic));
		redisMessageListenerContainer.addMessageListener(subscribeListener, new ChannelTopic("wsms"));

	}
	
	@OnClose
	public void onClose(Session session){
		System.out.println("java websocket:关闭连接");
		clients.remove(key);
		//sessions.remove(this);
	}
	
	@OnMessage
	//public void onMessage(Session session,String message,@PathParam("topic")String topic,@PathParam("myname")String myname) throws IOException{
	public void onMessage(Session session,String message,@PathParam("myname")String myname) throws IOException{
		SendMessageBean sendMessageBean = JsonUtil.jsonToPojo(message,SendMessageBean.class);
		sendMessageBean.setSendId(myname);
		message = JsonUtil.objectToJson(sendMessageBean);
		//message = myname+"："+message;
//		System.out.println("send myname: " + this.myname);
//		System.out.println("send key: " + this.key);
//		System.out.println("java websocket 收到消息=="+message);
		PublishService publishService = SpringUtils.getBean(PublishService.class);
		publishService.publish("wsms", message);
	}
	
	@OnError
	public void onError(Session session,Throwable error){
		System.out.println("java websocket 出现错误");
	}

	public Session getSession() {
		return session;
	}

	public void setSession(Session session) {
		this.session = session;
	}

	public static Map<String, WebsocketEndpoint> getClients() {
		return clients;
	}

	public static void setClients(Map<String, WebsocketEndpoint> clients) {
		WebsocketEndpoint.clients = clients;
	}

	public String getMyname() {
		return myname;
	}

	public void setMyname(String myname) {
		this.myname = myname;
	}

	public String getKey() {
		return key;
	}

	public void setKey(String key) {
		this.key = key;
	}
}
